from django.shortcuts import render, get_object_or_404, redirect
from django.views import generic
from django.urls import reverse_lazy
from django.db.models import Count
from django.contrib import messages
from .models import Area, Audience, Exhibitor, Exhibit, Schedule, Attendance, EventDetails, ExhibitInfo, Performer, Show, Audienceinfo, Equipment, News
from django.http import HttpResponse, JsonResponse
from django.db import connection
from django.core.serializers.json import DjangoJSONEncoder
import json
import csv
import io
from django.contrib.auth.decorators import login_required
from django import forms
from django.forms import ModelForm

# Create your views here.

# 首页
def index(request):
    areas_count = Area.objects.count()
    exhibitors_count = Exhibitor.objects.count()
    exhibits_count = Exhibit.objects.count()
    events_count = Schedule.objects.count()
    
    # 获取即将到来的活动
    upcoming_events = Schedule.objects.order_by('event_time')[:5]
    
    context = {
        'areas_count': areas_count,
        'exhibitors_count': exhibitors_count,
        'exhibits_count': exhibits_count,
        'events_count': events_count,
        'upcoming_events': upcoming_events,
    }
    return render(request, 'airshow/index.html', context)

# 区域列表视图
class AreaListView(generic.ListView):
    model = Area
    context_object_name = 'areas'
    template_name = 'airshow/area_list.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['areas_with_exhibitors'] = Area.objects.annotate(exhibitor_count=Count('exhibitor'))
        return context

# 区域详情视图
class AreaDetailView(generic.DetailView):
    model = Area
    context_object_name = 'area'
    template_name = 'airshow/area_detail.html'
    pk_url_kwarg = 'area_id'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['exhibitors'] = Exhibitor.objects.filter(area=self.object)
        return context

# 参展商列表视图
class ExhibitorListView(generic.ListView):
    model = Exhibitor
    context_object_name = 'exhibitors'
    template_name = 'airshow/exhibitor_list.html'
    
    def get_queryset(self):
        queryset = super().get_queryset()
        area_id = self.request.GET.get('area_id')
        if area_id:
            queryset = queryset.filter(area_id=area_id)
        return queryset
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['areas'] = Area.objects.all()
        return context

# 参展商详情视图
class ExhibitorDetailView(generic.DetailView):
    model = Exhibitor
    context_object_name = 'exhibitor'
    template_name = 'airshow/exhibitor_detail.html'
    pk_url_kwarg = 'exhibitor_id'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['exhibits'] = Exhibit.objects.filter(exhibitor=self.object)
        return context

# 活动日程列表视图
class ScheduleListView(generic.ListView):
    model = Schedule
    context_object_name = 'events'
    template_name = 'airshow/schedule_list.html'
    
    def get_queryset(self):
        return Schedule.objects.order_by('event_time')

# 活动日程详情视图
class ScheduleDetailView(generic.DetailView):
    model = Schedule
    context_object_name = 'event'
    template_name = 'airshow/schedule_detail.html'
    pk_url_kwarg = 'event_id'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 获取该活动的所有参与者
        context['attendees'] = Audience.objects.filter(attendance__show=self.object)
        return context

# 展品信息列表视图
class ExhibitInfoListView(generic.ListView):
    model = Exhibit
    context_object_name = 'exhibits'
    template_name = 'airshow/exhibit_info_list.html'
    
    def get_queryset(self):
        queryset = super().get_queryset()
        return queryset
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['categories'] = []
        context['area_names'] = Area.objects.values_list('name', flat=True).distinct()
        return context

# 活动详情列表视图
class EventDetailsListView(generic.ListView):
    model = Schedule
    context_object_name = 'events'
    template_name = 'airshow/event_details_list.html'
    
    def get_queryset(self):
        queryset = Schedule.objects.select_related('area', 'exhibitor', 'exhibit')
        area_id = self.request.GET.get('area_id')
        if area_id:
            queryset = queryset.filter(area_id=area_id)
        return queryset.order_by('event_time')
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['areas'] = Area.objects.all()
        return context

# 观众信息列表视图
class AudienceInfoListView(generic.ListView):
    model = Audienceinfo
    context_object_name = 'audiences'
    template_name = 'airshow/audience_info_list.html'
    paginate_by = 10
    
    def get_queryset(self):
        queryset = super().get_queryset()
        # 可以添加搜索和过滤逻辑
        return queryset.order_by('name')
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 添加额外的上下文数据
        context['total_count'] = self.get_queryset().count()
        return context

# 观众信息详情视图
class AudienceInfoDetailView(generic.DetailView):
    model = Audienceinfo
    context_object_name = 'audience'
    template_name = 'airshow/audience_info_detail.html'
    pk_url_kwarg = 'pk'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 可以添加额外的上下文数据
        return context

def get_model_by_table_name(table_name):
    """根据表名获取对应的模型类"""
    table_model_map = {
        'area': Area,
        'audience': Audience,
        'exhibitor': Exhibitor,
        'exhibit': Exhibit,
        'schedule': Schedule,
        'attendance': Attendance,
        'performer': Performer,
        'show': Show,
        'audienceinfo': Audienceinfo,
        'equipment': Equipment,
        'news': News
    }
    return table_model_map.get(table_name.lower())

def get_model_fields(model):
    """获取模型的字段信息"""
    return [field.name for field in model._meta.get_fields() if not field.is_relation]

@login_required
def direct_data_view(request, table):
    """通用数据管理视图"""
    model = get_model_by_table_name(table)
    if not model:
        messages.error(request, f'表 {table} 不存在')
        return redirect('airshow:index')
    
    # 获取字段列表
    columns = []
    for field in model._meta.get_fields():
        if not field.is_relation or field.many_to_one:
            columns.append(field.name)
    
    # 获取数据
    queryset = model.objects.all()
    data = []
    for obj in queryset:
        item = {}
        # 处理普通字段
        for field in columns:
            item[field] = getattr(obj, field)
        # 处理外键字段
        for field in model._meta.get_fields():
            if field.is_relation and field.many_to_one:
                related_obj = getattr(obj, field.name)
                if related_obj:
                    # 获取外键字段的名称
                    fk_name = field.name
                    # 获取外键字段的值
                    fk_value = getattr(related_obj, field.remote_field.field_name)
                    item[fk_name] = fk_value
        data.append(item)
    
    context = {
        'table': table,
        'columns': columns,
        'data': data,
    }
    return render(request, 'airshow/direct_data.html', context)

@login_required
def add_data_view(request, table):
    """通用添加数据视图"""
    model = get_model_by_table_name(table)
    if not model:
        messages.error(request, f'表 {table} 不存在')
        return redirect('airshow:index')
    
    if request.method == 'POST':
        try:
            data = {}
            for field in get_model_fields(model):
                if field in request.POST:
                    data[field] = request.POST.get(field)
            obj = model.objects.create(**data)
            messages.success(request, '添加成功')
            return redirect('airshow:direct_data', table=table)
        except Exception as e:
            messages.error(request, f'添加失败：{str(e)}')
    
    context = {
        'table': table,
        'columns': get_model_fields(model),
    }
    return render(request, 'airshow/add_data.html', context)

def get_model_form(model_class):
    """根据模型动态生成表单类"""
    class DynamicModelForm(ModelForm):
        class Meta:
            model = model_class
            fields = '__all__'
    return DynamicModelForm

@login_required
def edit_data_view(request, table, pk):
    """通用编辑数据视图"""
    model = get_model_by_table_name(table)
    if not model:
        messages.error(request, f'表 {table} 不存在')
        return redirect('airshow:index')
    
    item = get_object_or_404(model, pk=pk)
    if request.method == 'POST':
        form = get_model_form(model)(request.POST, instance=item)
        if form.is_valid():
            form.save()
            messages.success(request, '更新成功')
            return redirect('airshow:direct_data', table=table)
    else:
        form = get_model_form(model)(instance=item)
    
    return render(request, 'airshow/edit_data.html', {
        'form': form,
        'table': table,
        'item': item
    })

@login_required
def delete_data_view(request, table, pk):
    """通用删除数据视图"""
    model = get_model_by_table_name(table)
    if not model:
        messages.error(request, f'表 {table} 不存在')
        return redirect('airshow:index')
    
    try:
        item = get_object_or_404(model, pk=pk)
        if request.method == 'POST':
            item.delete()
            messages.success(request, '删除成功')
            return redirect('airshow:direct_data', table=table)
        
        return render(request, 'airshow/delete_data.html', {
            'table': table,
            'item': item
        })
    except Exception as e:
        messages.error(request, f'删除失败：{str(e)}')
        return redirect('airshow:direct_data', table=table)

@login_required
def export_data_view(request, table):
    """导出数据为CSV"""
    model = get_model_by_table_name(table)
    if not model:
        messages.error(request, f'表 {table} 不存在')
        return redirect('airshow:index')
    
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = f'attachment; filename="{table}_export.csv"'
    
    writer = csv.writer(response)
    fields = get_model_fields(model)
    
    # 写入表头
    writer.writerow(fields)
    
    # 写入数据
    for obj in model.objects.all():
        row = [getattr(obj, field) for field in fields]
        writer.writerow(row)
    
    return response

@login_required
def import_data_view(request, table):
    """从CSV导入数据"""
    model = get_model_by_table_name(table)
    if not model:
        messages.error(request, f'表 {table} 不存在')
        return redirect('airshow:index')
    
    if request.method == 'POST' and request.FILES.get('csv_file'):
        try:
            csv_file = request.FILES['csv_file']
            decoded_file = csv_file.read().decode('utf-8')
            csv_data = csv.reader(io.StringIO(decoded_file))
            
            # 跳过表头
            headers = next(csv_data)
            fields = get_model_fields(model)
            
            # 验证表头
            if not all(header in fields for header in headers):
                messages.error(request, 'CSV文件的列名与数据表不匹配')
                return redirect('airshow:direct_data', table=table)
            
            # 导入数据
            for row in csv_data:
                data = dict(zip(headers, row))
                model.objects.create(**data)
            
            messages.success(request, '数据导入成功')
        except Exception as e:
            messages.error(request, f'导入失败：{str(e)}')
        
        return redirect('airshow:direct_data', table=table)
    
    context = {
        'table': table,
    }
    return render(request, 'airshow/import_data.html', context)

# 区域管理
@login_required
def area_list(request):
    areas = Area.objects.all()
    return render(request, 'airshow/area_management.html', {'areas': areas})

@login_required
def area_add(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        location = request.POST.get('location')
        Area.objects.create(name=name, location=location)
        return redirect('airshow:area_list')
    return render(request, 'airshow/area_form.html')

@login_required
def area_edit(request, pk):
    area = get_object_or_404(Area, area_id=pk)
    if request.method == 'POST':
        area.name = request.POST.get('name')
        area.location = request.POST.get('location')
        area.save()
        return redirect('airshow:area_list')
    return render(request, 'airshow/area_form.html', {'area': area})

@login_required
def area_delete(request, pk):
    area = get_object_or_404(Area, area_id=pk)
    area.delete()
    return redirect('airshow:area_list')

# 表演者管理
@login_required
def performer_list(request):
    performers = Performer.objects.all()
    return render(request, 'airshow/performer_list.html', {'performers': performers})

@login_required
def performer_add(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        nationality = request.POST.get('nationality')
        info = request.POST.get('info')
        image = request.POST.get('image')
        Performer.objects.create(name=name, nationality=nationality, info=info, image=image)
        return redirect('airshow:performer_list')
    return render(request, 'airshow/performer_form.html')

@login_required
def performer_edit(request, pk):
    performer = get_object_or_404(Performer, pk=pk)
    if request.method == 'POST':
        performer.name = request.POST.get('name')
        performer.nationality = request.POST.get('nationality')
        performer.info = request.POST.get('info')
        performer.image = request.POST.get('image')
        performer.save()
        return redirect('airshow:performer_list')
    return render(request, 'airshow/performer_form.html', {'performer': performer})

@login_required
def performer_delete(request, pk):
    performer = get_object_or_404(Performer, pk=pk)
    performer.delete()
    return redirect('airshow:performer_list')

# 演出管理
@login_required
def show_list(request):
    shows = Show.objects.all()
    return render(request, 'airshow/show_list.html', {'shows': shows})

@login_required
def show_add(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        performer_id = request.POST.get('performer')
        area_id = request.POST.get('area')
        time = request.POST.get('time')
        ticket = request.POST.get('ticket')
        info = request.POST.get('info')
        
        performer = None if not performer_id else get_object_or_404(Performer, pk=performer_id)
        area = None if not area_id else get_object_or_404(Area, pk=area_id)
        
        Show.objects.create(
            name=name,
            performer=performer,
            area=area,
            time=time,
            ticket=ticket,
            info=info
        )
        return redirect('airshow:show_list')
    
    performers = Performer.objects.all()
    areas = Area.objects.all()
    return render(request, 'airshow/show_form.html', {
        'performers': performers,
        'areas': areas
    })

@login_required
def show_edit(request, pk):
    show = get_object_or_404(Show, pk=pk)
    if request.method == 'POST':
        show.name = request.POST.get('name')
        performer_id = request.POST.get('performer')
        area_id = request.POST.get('area')
        show.time = request.POST.get('time')
        show.ticket = request.POST.get('ticket')
        show.info = request.POST.get('info')
        
        show.performer = None if not performer_id else get_object_or_404(Performer, pk=performer_id)
        show.area = None if not area_id else get_object_or_404(Area, pk=area_id)
        
        show.save()
        return redirect('airshow:show_list')
    
    performers = Performer.objects.all()
    areas = Area.objects.all()
    return render(request, 'airshow/show_form.html', {
        'show': show,
        'performers': performers,
        'areas': areas
    })

@login_required
def show_delete(request, pk):
    show = get_object_or_404(Show, pk=pk)
    show.delete()
    return redirect('airshow:show_list')

# 观众管理
@login_required
def audience_list(request):
    audiences = Audienceinfo.objects.all()
    return render(request, 'airshow/audience_list.html', {'audiences': audiences})

@login_required
def audience_add(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        tel = request.POST.get('tel')
        note = request.POST.get('note')
        Audienceinfo.objects.create(name=name, tel=tel, note=note)
        return redirect('airshow:audience_list')
    return render(request, 'airshow/audience_form.html')

@login_required
def audience_edit(request, pk):
    audience = get_object_or_404(Audienceinfo, pk=pk)
    if request.method == 'POST':
        audience.name = request.POST.get('name')
        audience.tel = request.POST.get('tel')
        audience.note = request.POST.get('note')
        audience.save()
        return redirect('airshow:audience_list')
    return render(request, 'airshow/audience_form.html', {'audience': audience})

@login_required
def audience_delete(request, pk):
    audience = get_object_or_404(Audienceinfo, pk=pk)
    audience.delete()
    return redirect('airshow:audience_list')

# 设备管理
@login_required
def equipment_list(request):
    equipment = Equipment.objects.all()
    return render(request, 'airshow/equipment_list.html', {'equipment': equipment})

@login_required
def equipment_add(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        model = request.POST.get('model')
        performer_id = request.POST.get('performer')
        info = request.POST.get('info')
        
        performer = None if not performer_id else get_object_or_404(Performer, pk=performer_id)
        
        Equipment.objects.create(
            name=name,
            model=model,
            performer=performer,
            info=info
        )
        return redirect('airshow:equipment_list')
    
    performers = Performer.objects.all()
    return render(request, 'airshow/equipment_form.html', {'performers': performers})

@login_required
def equipment_edit(request, pk):
    equipment = get_object_or_404(Equipment, pk=pk)
    if request.method == 'POST':
        equipment.name = request.POST.get('name')
        equipment.model = request.POST.get('model')
        performer_id = request.POST.get('performer')
        equipment.info = request.POST.get('info')
        
        equipment.performer = None if not performer_id else get_object_or_404(Performer, pk=performer_id)
        
        equipment.save()
        return redirect('airshow:equipment_list')
    
    performers = Performer.objects.all()
    return render(request, 'airshow/equipment_form.html', {
        'equipment': equipment,
        'performers': performers
    })

@login_required
def equipment_delete(request, pk):
    equipment = get_object_or_404(Equipment, pk=pk)
    equipment.delete()
    return redirect('airshow:equipment_list')

# 新闻管理
@login_required
def news_list(request):
    news = News.objects.all()
    return render(request, 'airshow/news_list.html', {'news': news})

@login_required
def news_add(request):
    if request.method == 'POST':
        title = request.POST.get('title')
        content = request.POST.get('content')
        date = request.POST.get('date')
        image = request.POST.get('image')
        News.objects.create(title=title, content=content, date=date, image=image)
        return redirect('airshow:news_list')
    return render(request, 'airshow/news_form.html')

@login_required
def news_edit(request, pk):
    news = get_object_or_404(News, pk=pk)
    if request.method == 'POST':
        news.title = request.POST.get('title')
        news.content = request.POST.get('content')
        news.date = request.POST.get('date')
        news.image = request.POST.get('image')
        news.save()
        return redirect('airshow:news_list')
    return render(request, 'airshow/news_form.html', {'news': news})

@login_required
def news_delete(request, pk):
    news = get_object_or_404(News, pk=pk)
    news.delete()
    return redirect('airshow:news_list')

# 参与管理
@login_required
def attendance_list(request):
    attendances = Attendance.objects.all()
    return render(request, 'airshow/attendance_list.html', {'attendances': attendances})

@login_required
def attendance_add(request):
    if request.method == 'POST':
        show_id = request.POST.get('show')
        audience_id = request.POST.get('audience')
        seatinfo = request.POST.get('seatinfo')
        
        show = get_object_or_404(Schedule, pk=show_id)
        audience = get_object_or_404(Audience, pk=audience_id)
        
        Attendance.objects.create(
            show=show,
            audience=audience,
            seatinfo=seatinfo
        )
        return redirect('airshow:attendance_list')
    
    shows = Schedule.objects.all()
    audiences = Audience.objects.all()
    return render(request, 'airshow/attendance_form.html', {
        'shows': shows,
        'audiences': audiences
    })

@login_required
def attendance_edit(request, pk):
    attendance = get_object_or_404(Attendance, pk=pk)
    if request.method == 'POST':
        show_id = request.POST.get('show')
        audience_id = request.POST.get('audience')
        attendance.seatinfo = request.POST.get('seatinfo')
        
        attendance.show = get_object_or_404(Schedule, pk=show_id)
        attendance.audience = get_object_or_404(Audience, pk=audience_id)
        
        attendance.save()
        return redirect('airshow:attendance_list')
    
    shows = Schedule.objects.all()
    audiences = Audience.objects.all()
    return render(request, 'airshow/attendance_form.html', {
        'attendance': attendance,
        'shows': shows,
        'audiences': audiences
    })

@login_required
def attendance_delete(request, pk):
    attendance = get_object_or_404(Attendance, pk=pk)
    attendance.delete()
    return redirect('airshow:attendance_list')
